﻿
namespace GSBA.DataImporter
{
    using Ionic.Zip;
    using System;
    using System.Collections.Generic;
    using System.Text.RegularExpressions;
    using System.Xml;

    public sealed class DataArchive
    {
        private const string ListingsDataFileName = "Listings";
        private const string NeighborhoodsDataFileName = "Neighborhoods";

        private static readonly Regex DataFileNameExpression = new Regex(@"^\d+_iPhone(?<Name>.*)Data\.xml$", RegexOptions.Compiled);

        private readonly DataTable<ListingRow> listings;
        private readonly DataTable<NeighborhoodRow> neighborhoods;

        private DataArchive(DataTable<ListingRow> listingsTable, DataTable<NeighborhoodRow> neighborhoodsTable)
        {
            this.listings = listingsTable;
            this.neighborhoods = neighborhoodsTable;
        }

        public DataTable<ListingRow> Listings
        {
            get { return this.listings; }
        }

        public DataTable<NeighborhoodRow> Neighborhoods
        {
            get { return this.neighborhoods; }
        }

        public static DataArchive Open(string filename)
        {
            if (string.IsNullOrEmpty(filename))
            {
                throw new ArgumentNullException("filename");
            }

            var data = DataArchive.GetDataFiles(filename);

            DataTable<ListingRow> listingsTable = null;
            if (data.ContainsKey(DataArchive.ListingsDataFileName))
            {
                listingsTable = DataTable.Create<ListingRow>(DataArchive.ListingsDataFileName, data[DataArchive.ListingsDataFileName]);
            }

            DataTable<NeighborhoodRow> neighborhoodsTable = null;
            if (data.ContainsKey(DataArchive.NeighborhoodsDataFileName))
            {
                neighborhoodsTable = DataTable.Create<NeighborhoodRow>(DataArchive.NeighborhoodsDataFileName, data[DataArchive.NeighborhoodsDataFileName]);
            }

            return new DataArchive(listingsTable, neighborhoodsTable);
        }

        private static IDictionary<string, XmlDocument> GetDataFiles(string filename)
        {
            var result = new Dictionary<string, XmlDocument>();
            var archive = ZipFile.Read(filename);
            foreach (var entry in archive)
            {
                var fileNameMatch = DataArchive.DataFileNameExpression.Match(entry.FileName);
                if (fileNameMatch.Success)
                {
                    var name = fileNameMatch.Groups["Name"].Value + "s";
                    using (var contentStream = entry.OpenReader())
                    {
                        var xml = new XmlDocument();
                        xml.Load(contentStream);
                        result.Add(name, xml);
                    }
                }
            }

            return result;
        }
    }
}
